using System;
using Lucene.Net.Documents;
using Lucene.Net.Index;

namespace SpellCenter.Core
{
    static internal class DocumentHelper
    {
        public const string ID = "id";
        public const string FORMAT = "format";
        public const string FILENAME = "filename";
        public const string TEXT = "text";
        public const string TAG = "tag";
        public const string START = "start";
        public const string END = "end";
        public const string BOOK = "book";
        public const string CHAPTER = "chap";
        public const string VERSE = "vs";

        /// <summary>
        /// Gets tag name from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
        public static string GetTag(Document doc)
        {
          return GetFieldValueAsString(doc, TAG);
        }

        /// <summary>
        /// Gets file name from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
        public static string GetFileName(Document doc)
        {
          return GetFieldValueAsString(doc, FILENAME);
        }

      public static string GetReference(Document document)
      {
          string reference = GetBook(document);
          string chapter = GetChapter(document);
          if (chapter.Length != 0)
          {
            reference += ' ' + chapter;
            string verse = GetVerse(document);
            if (verse.Length != 0)
            {
              reference += ':' + verse;
            }
          }
          return reference;
      }
      /// <summary>
        /// Gets character offset within the file where the document starts
        /// </summary>
        /// <value><code>&lt;0</code> if not set</value>
        static public long GetStartOfDocInFile(Document doc, IndexReader reader)
        {
                long whereLuceneThinksItStarts = GetFieldValueAsLong(doc, START);
                  return
                    whereLuceneThinksItStarts +
                    FragmentMovementTracker.GetStartCorrection(reader, GetFileName(doc),
                                                               whereLuceneThinksItStarts);
        }
        /// <summary>
        /// Get the Start without information from FragmentMovementTracker factored in (offsets)
        /// </summary>
        public static long GetRawStart(Document doc)
        {
            return GetFieldValueAsLong(doc, START); 
        }

      public static long GetOffset(Document document, IndexReader reader)
      {
          return GetStartOfDocInFile(document, reader) +
            GetTag(document).Length + 1;
      }

        /// <summary>
        /// Gets character offset within the file where the document ends and before the next tag begins
        /// </summary>
        /// <value><code>&lt;0</code> if not set</value>
        public static long GetEnd(Document doc, IndexReader reader)
        {
                long val = GetFieldValueAsLong(doc, END);
                  return val + FragmentMovementTracker.GetEndCorrection(reader, GetFileName(doc), val);
        }
        /// <summary>
        /// Get the End without information from FragmentMovementTracker factored in (offsets)
        /// </summary>
        public static long GetRawEnd(Document doc)
        {
            return GetFieldValueAsLong(doc, END); 
        }
        /// <summary>
        /// Gets file format from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
        public static string GetFormat(Document doc)
        {
          return GetFieldValueAsString(doc, FORMAT);
        }
        /// <summary>
        /// Gets book code from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
      public static string GetBook(Document doc)
        {
          return GetFieldValueAsString(doc, BOOK);
        }
        /// <summary>
        /// Gets chapter from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
        public static string GetChapter(Document doc)
        {
          return GetFieldValueAsString(doc, CHAPTER);
        }
        /// <summary>
        /// Gets verse from document
        /// </summary>
        /// <value><code>string.Empty</code> if not set</value>
      public static string GetVerse(Document doc)
        {
          return GetFieldValueAsString(doc, VERSE);
        }
        /// <summary>
        /// Returns a unique identifier so that a document can be identified with a single Term.
        /// </summary>
        /// <value>Unique identifier for this document</value>
        public static Guid GetId(Document doc)
        {
          string value = GetFieldValueAsString(doc, ID);
          if(value.Length == 0)
          {
            return Guid.Empty;
          }
          return new Guid(value);
        }

        private static string GetFieldValueAsString(Document doc, string fieldname)
        {
          Field field = doc.GetField(fieldname);
          if (field == null)
          {
            return string.Empty;
          }
          return field.StringValue();
        }

        private static long GetFieldValueAsLong(Document doc, string fieldname)
        {
          Field field = doc.GetField(fieldname);
          if (field == null)
          {
            return -1;
          }
          return long.Parse(field.StringValue());
        }

      public static Document CreateDocument(string tag, 
                                            string text, 
                                            string filename, 
                                            string start, 
                                            string end, 
                                            string book, 
                                            string chapter, 
                                            string verse, 
                                            Guid id)
      {
        Document doc = new Document();
        doc.Add(new Field(TAG, tag, Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(TEXT, text, Field.Store.NO, Field.Index.TOKENIZED));
        doc.Add(new Field(FILENAME, filename, Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(START, start, Field.Store.YES, Field.Index.NO));
        doc.Add(new Field(END, end, Field.Store.YES, Field.Index.NO));
        doc.Add(new Field(FORMAT, "SFM", Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(BOOK, book, Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(CHAPTER, chapter, Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(VERSE, verse, Field.Store.YES, Field.Index.UN_TOKENIZED));
        doc.Add(new Field(ID, id.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
        return doc;

      }

    }
}
